package com.ihr360.insurance.service.impl;

import com.google.common.collect.Lists;
import com.ihr360.authority.sharing.service.AuthUserResourceService;
import com.ihr360.commons.data.util.Pair;
import com.ihr360.commons.exception.Ihr360Exception;
import com.ihr360.commons.lang.CollectionUtils;
import com.ihr360.commons.lang.StringUtils;
import com.ihr360.commons.model.type.SIHFLedgerState;
import com.ihr360.entity.ApplicationApprovalEntity;
import com.ihr360.insurance.dao.MonthlyLedgerSummaryReposity;
import com.ihr360.insurance.entity.response.BenefitApprovalResponse;
import com.ihr360.insurance.model.dto.ledger.MonthlyLedgerSummary;
import com.ihr360.insurance.model.dto.ledger.embeddable.HouseFundLedgerSummary;
import com.ihr360.insurance.model.dto.ledger.embeddable.SocialInsuranceLedgerSummary;
import com.ihr360.insurance.service.DecreaseMemberService;
import com.ihr360.insurance.service.IncreaseMemberService;
import com.ihr360.insurance.service.MonthlyLedgerService;
import com.ihr360.insurance.service.MonthlyLedgerSummaryService;
import com.ihr360.rest.reposity.SimpleRestReposity;
import com.ihr360.rest.service.AbstractSimpleRestServiceImpl;
import com.ihr360.validation.ValidationUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author Stone.Shi
 * @description
 * @date 2018-02-13 17:22:54.
 */
@Service
public class MonthlyLedgerSummaryServiceImpl extends AbstractSimpleRestServiceImpl<MonthlyLedgerSummary, Long> implements MonthlyLedgerSummaryService {
    @Autowired
    private MonthlyLedgerSummaryReposity reposity;

    @Autowired
    private MonthlyLedgerService ledgerService;

    @Autowired
    private IncreaseMemberService increaseMemberService;

    @Autowired
    private DecreaseMemberService decreaseMemberService;

    @Autowired
    private AuthUserResourceService authUserResourceService;

    @Override
    public SimpleRestReposity<MonthlyLedgerSummary, Long> getSimpleRestReposity() {
        return reposity;
    }

    @Override
    public Pair<Long, String> getLedgerSummaryUserId(String companyId, String applicationId) {
        MonthlyLedgerSummary ledgerSummary = reposity.findByCompanyIdAndApplicationId(companyId, applicationId);
        if (ledgerSummary != null) {
            return Pair.of(ledgerSummary.getId(), ledgerSummary.getUserId());
        }
        return null;
    }

    @Override
    public boolean isLedgerExisted(String companyId, String userId, Integer ledgerYear, Integer ledgerMonth) {
        validateLedgerDate(ledgerYear, ledgerMonth);
        return reposity.countByCompanyIdAndUserIdAndLedgerYearAndLedgerMonth(
                companyId, userId, ledgerYear, ledgerMonth) == 1;
    }

    @Override
    public MonthlyLedgerSummary getLedgerSummary(String companyId, String userId, Integer ledgerYear, Integer ledgerMonth) {
        validateLedgerDate(ledgerYear, ledgerMonth);
        return reposity.findByCompanyIdAndUserIdAndAndLedgerYearAndLedgerMonth(
                companyId, userId, ledgerYear, ledgerMonth);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MonthlyLedgerSummary createLedgerSummary(String companyId, String userId, Integer ledgerYear, Integer ledgerMonth) {
        validateLedgerDate(ledgerYear, ledgerMonth);
        MonthlyLedgerSummary summary = new MonthlyLedgerSummary();
        summary.setCompanyId(companyId);
        summary.setLedgerYear(ledgerYear);
        summary.setLedgerMonth(ledgerMonth);
        summary.setLedgerState(SIHFLedgerState.ADJUST);
        summary.setUserId(userId);

        summary.setSiLedgerSummary(new SocialInsuranceLedgerSummary());
        summary.getSiLedgerSummary().setSiMemberCount(0);
        summary.getSiLedgerSummary().setSiCost(BigDecimal.ZERO);
        summary.setHfLedgerSummary(new HouseFundLedgerSummary());
        summary.getHfLedgerSummary().setHfMemberCount(0);
        summary.getHfLedgerSummary().setHfCost(BigDecimal.ZERO);
        return reposity.save(summary);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveLedgerSummary(MonthlyLedgerSummary ledgerSummary) {
        reposity.save(ledgerSummary);
    }

    @Override
    public void deleteOne(Long id) {
        MonthlyLedgerSummary ledgerSummary = super.getOne(id);
        ValidationUtils.rejectIfEmpty(ledgerSummary, "", "月度台账不存在，请刷新重试");
        super.deleteOne(id);
        String companyId = ledgerSummary.getCompanyId();
        String userId = ledgerSummary.getUserId();
        Integer ledgerYear = ledgerSummary.getLedgerYear();
        Integer ledgerMonth = ledgerSummary.getLedgerMonth();
        ledgerService.deleteLedger(companyId, userId, ledgerYear, ledgerMonth);
        increaseMemberService.deleteIncreaseMemberRecords(companyId, userId, ledgerYear, ledgerMonth);
        decreaseMemberService.deleteDecreaseMemberRecords(companyId, userId, ledgerYear, ledgerMonth);
    }

    @Override
    public boolean isLedgerLocked(String companyId, String userId, Integer ledgerYear, Integer ledgerMonth) {
        validateLedgerDate(ledgerYear, ledgerMonth);
        return reposity.countByCompanyIdAndUserIdAndLedgerYearAndLedgerMonthAndLedgerState(
                companyId, userId, ledgerYear, ledgerMonth, SIHFLedgerState.CLOSED) == 1;
    }

    private void validateLedgerDate(Integer ledgerYear, Integer ledgerMonth) {
        ValidationUtils.rejectIfEmpty(ledgerYear, "", "台账年份不能为空");
        ValidationUtils.rejectIfEmpty(ledgerMonth, "", "台账月份不能为空");
        ValidationUtils.rejectNotInRange(ledgerMonth, 1, 12, "", "台账月份无效");
    }

    @Override
    public List<BenefitApprovalResponse> queryApprovalBenefit(String companyId, List<String> applicationIdList) {
        List<BenefitApprovalResponse> list = Lists.newArrayList();
        List<MonthlyLedgerSummary> summaryList = reposity.findByCompanyIdAndApplicationIdIn(companyId, applicationIdList);
        if (CollectionUtils.isEmpty(summaryList)) {
            return list;
        }
        summaryList.forEach(summary -> {
            BenefitApprovalResponse response = new BenefitApprovalResponse();
            response.setId(summary.getId());
            response.setApplicationId(summary.getApplicationId());
            String date = summary.getLedgerYear() + "-" + summary.getLedgerMonth();
            response.setPayDate(date);
            if (summary.getSiLedgerSummary() != null) {
                response.setSiNumber(summary.getSiLedgerSummary().getSiMemberCount());
            }
            if (summary.getHfLedgerSummary() != null) {
                response.setHfNumber(summary.getHfLedgerSummary().getHfMemberCount());
            }
            list.add(response);
        });
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateApprovalState(String companyId, String applicationId, SIHFLedgerState state) {
        MonthlyLedgerSummary summary = reposity.findByCompanyIdAndApplicationId(companyId, applicationId);
        if (summary == null) {
            throw new Ihr360Exception(null, "该账期记录不存在");
        }
        summary.setLedgerState(state);
        reposity.save(summary);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveApprovalApplicationId(String companyId, ApplicationApprovalEntity entity, Long id) {
        String applicationId = entity.getApplicationId();
        List<String> approvalStaffList = entity.getApprovalStaffList();
        if (StringUtils.isEmpty(applicationId)) {
            throw new Ihr360Exception(null, "审批记录id不可为空");
        }
        MonthlyLedgerSummary summary = super.getOne(id);
        if (summary == null) {
            throw new Ihr360Exception(null, "该账期记录不存在");
        }
        summary.setApplicationId(applicationId);
        summary.setLedgerState(SIHFLedgerState.APPROVING);
        reposity.save(summary);
        //审批时手动为审批人添加数据权限，web-staff端调用接口使用
        if (CollectionUtils.isNotEmpty(approvalStaffList)) {
            authUserResourceService.addUserResource(companyId, MonthlyLedgerSummary.class.getSimpleName(), approvalStaffList, id.toString());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void closeLedgerSummary(Long id) {
        MonthlyLedgerSummary ledgerSummary = super.getOne(id);
        ValidationUtils.rejectIfEmpty(ledgerSummary, "", "月度台账不存在，请刷新重试");
        ledgerSummary.setLedgerState(SIHFLedgerState.CLOSED);
        reposity.save(ledgerSummary);
    }
}
